package org.example.domain.strategy.service.algorithm;

import org.example.domain.strategy.model.vo.AwardRateInfo;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zxc
 */
public abstract class BaseAlgorithm implements IDrawAlgorithm{
    private final int HASH_INCREMENT = 0x61c88647;

    private final int RATE_TUPLE_LENGTH = 128;

    // 存放概率与奖品对应的散列结果，strategyId -> rateTuple

    protected Map<Long,String[]> rateTupleMap = new ConcurrentHashMap<>();

    // 奖品区间概率值，strategyId -> [awardId->begin、awardId->end]

    protected Map<Long,List<AwardRateInfo>> awardRateInfoMap = new ConcurrentHashMap<>();


    @Override
    public void initRateTuple(Long strategyId, List<AwardRateInfo> awardRateInfoList) {
        //保存策略id与对应策略下获奖概率信息
        awardRateInfoMap.put(strategyId,awardRateInfoList);
        //通过策略id获取对应的散列结果，如果没有就创建一个新的[0-127]
        String[] rateTuple = rateTupleMap.computeIfAbsent(strategyId, k -> new String[RATE_TUPLE_LENGTH]);

        int cursorVal = 0;

        for (AwardRateInfo awardRateInfo : awardRateInfoList) {
            //例如一等奖，二等奖，三等奖的比例为0.2 0.3 0.5

            int rateVal = awardRateInfo.getAwardRate().multiply(new BigDecimal(100)).intValue();
            //所以在散列数列中，有20个一等奖、30个二等奖、50个三等奖
            for (int i = cursorVal + 1; i <= (rateVal + cursorVal);i++){
                rateTuple[hashIdx(i)] = awardRateInfo.getAwardId();
            }

            cursorVal += rateVal;

        }
    }

    @Override
    public boolean isExistRateTuple(Long strategyId) {
        return rateTupleMap.containsKey(strategyId);
    }



    protected int hashIdx(int val){
        int hashCode = val * HASH_INCREMENT + HASH_INCREMENT;
        return hashCode & (RATE_TUPLE_LENGTH - 1);
    }
}
